#include<stdio.h>
#include<stdlib.h>
#include<unistd.h>
#include<sys/types.h>
#include<sys/wait.h>

#define N 5
//int main()
//{
//    pid_t id = fork();
//    
//    if(id < 0)
//    {
//        perror("fork fail\n");
//        return 1;
//    }
//    else if(id == 0)
//    {
//        //child
//        int cnt = 5;
//        while(cnt)
//        { 
//            printf("I am a child, pid:%d, ppid:%d, cnt:%d\n", getpid(), getppid(), cnt);
//            cnt--;
//            sleep(1);
//        }
//        exit(0);
//    }
//    else
//    {
//        //parent
//        while(1)
//        {
//            printf("I am a father, pid:%d, ppid:%d\n", getpid(), getppid());
//            sleep(1);
//        }
//    }
//    //父子进程共享代码区
//    return 0;
//}

//int main()
//{
//    pid_t id = fork();
//    
//    if(id < 0)
//    {
//        perror("fork fail\n");
//        return 1;
//    }
//    else if(id == 0)
//    {
//        //child
//        int cnt = 5;
//        while(cnt)
//        { 
//            printf("I am a child, pid:%d, ppid:%d, cnt:%d\n", getpid(), getppid(), cnt);
//            cnt--;
//            sleep(1);
//        }
//        exit(0);
//    }
//    else
//    {
//        //parent
//        int cnt = 10;
//        while(cnt--)
//        {
//            printf("I am a father, pid:%d, ppid:%d, cnt:%d\n", getpid(), getppid(), cnt);
//            sleep(1);
//        }
//        //进程等待是必须的
//        //wait是等待任意一个子进程退出
//        
//        pid_t ret = wait(NULL);
//        if(ret == id)
//        {
//           printf("wait success, ret:%d\n", ret);
//        }
//        sleep(5);
//    }
//    //父子进程共享代码区
//    return 0;
//
//}

//void runchild()
//{
//    int cnt = 5;
//    while(cnt)
//    { 
//        printf("I am a child, pid:%d, ppid:%d, cnt:%d\n", getpid(), getppid(), cnt);
//        cnt--;
//        sleep(1);
//    }
//}
//
//int main()
//{
//    for(int i = 0; i < N; i++)
//    {
//        pid_t id = fork();
//
//        if(id == 0)
//        {
//            //child
//            runchild();
//            exit(0);
//        }
//        printf("create child process succuess\n");        
//    }
//
//    sleep(10);
//
//   //等待多个进程
//    for(int i = 0; i < N; i++)
//    {
//        pid_t ret =wait(NULL);
//        if(ret > 0)
//        {
//            printf("wait %d success\n", ret);
//        }
//    }
//
//    return 0;
//}

//waitpid的使用
//int main()
//{
//    pid_t id = fork();
//    
//    if(id < 0)
//    {
//        perror("fork fail\n");
//        return 1;
//    }
//    else if(id == 0)
//    {
//        //child
//        int cnt = 5;
//        while(cnt)
//        { 
//            printf("I am a child, pid:%d, ppid:%d, cnt:%d\n", getpid(), getppid(), cnt);
//            cnt--;
//            sleep(1);
//        }
//        exit(2);
//    }
//    else
//    {
//        //parent
//        int cnt = 10;
//        while(cnt--)
//        {
//            printf("I am a father, pid:%d, ppid:%d, cnt:%d\n", getpid(), getppid(), cnt);
//            sleep(1);
//        }
//        //进程等待是必须的
//        //wait是等待任意一个子进程退出
//        
//        int status = 0;
//        pid_t ret = waitpid(-1, &status, 0);
//        if(ret == id)
//        {
//           printf("wait success, ret:%d, status:%d\n", ret, status);
//        }
//        sleep(5);
//    }
//    //父子进程共享代码区
//    return 0;
//
//}

//int main()
//{
//    pid_t id = fork();
//    
//    if(id < 0)
//    {
//        perror("fork fail\n");
//        return 1;
//    }
//    else if(id == 0)
//    {
//        //child
//        int cnt = 5;
//        while(cnt)
//        { 
//            printf("I am a child, pid:%d, ppid:%d, cnt:%d\n", getpid(), getppid(), cnt);
//            cnt--;
//            sleep(1);
//        }
//       // int a = 0;
//       // a /= 0;
//       //int* p = NULL;
//       //*p = 100;
//        exit(1);
//    }
//    else
//    {
//        //parent
//        int cnt = 10;
//        while(cnt--)
//        {
//            printf("I am a father, pid:%d, ppid:%d, cnt:%d\n", getpid(), getppid(), cnt);
//            sleep(1);
//        }
//        //进程等待是必须的
//        //wait是等待任意一个子进程退出
//        
//        int status = 0;
//        pid_t ret = waitpid(id, &status, 0);
//        if(ret == id)
//        {
//            //printf("wait success, ret:%d, exit sig:%d, exit code:%d\n", ret, status&0x7f, (status>>8)&(0xff));
//            if(WIFEXITED(status))
//            {
//                printf("程序是正常跑完的, 退出码为%d\n", WEXITSTATUS(status));
//            }
//            else
//            {
//                printf("程序进入异常了\n");
//            }
//        }
//        else
//        {
//            printf("wait failed!\n");
//        }
//        sleep(5);
//    }
//
//    return 0;
//}

//void runchild()
//{
//    int cnt = 5;
//    while(cnt)
//    { 
//        printf("I am a child, pid:%d, ppid:%d, cnt:%d\n", getpid(), getppid(), cnt);
//        cnt--;
//        sleep(1);
//    }
//}
//
//int main()
//{
//    for(int i = 0; i < N; i++)
//    {
//        pid_t id = fork();
//
//        if(id == 0)
//        {
//            //child
//            runchild();
//            exit(i);
//        }
//        printf("create child process succuess\n");        
//    }
//
//    sleep(10);
//
//   //等待多个进程
//    for(int i = 0; i < N; i++)
//    {
//        int status = 0;
//        pid_t ret =waitpid(-1, &status, 0);
//        if(ret > 0)
//        {
//            printf("wait %d success, exit code:%d\n", ret, WEXITSTATUS(status));
//        }
//    }
//
//    return 0;
//}

//int main()
//{
//    pid_t id = fork();
//    
//    if(id < 0)
//    {
//        perror("fork fail\n");
//        return 1;
//    }
//    else if(id == 0)
//    {
//        //child
//        int cnt = 5;
//        while(cnt)
//        { 
//            printf("I am a child, pid:%d, ppid:%d, cnt:%d\n", getpid(), getppid(), cnt);
//            cnt--;
//            sleep(1);
//        }
//        exit(1);
//    }
//    else
//    {
//        //parent
//        //int cnt = 10;
//        //while(cnt--)
//        //{
//        //    printf("I am a father, pid:%d, ppid:%d, cnt:%d\n", getpid(), getppid(), cnt);
//        //    sleep(1);
//        //}
//        //进程等待是必须的
//        //wait是等待任意一个子进程退出
//        
//        int status = 0;
//        while(1)
//        {
//            //提供非阻塞轮询
//            pid_t ret = waitpid(id, &status, WNOHANG);
//            if(ret > 0)
//            {
//                if(WIFEXITED(status))
//                {
//                    printf("进程正常跑完，退出码为%d\n", WEXITSTATUS(status));
//                    break;
//                }
//                else
//                {
//                    printf("程序异常\n");
//                    break;
//                }
//            }
//            else if(ret < 0)
//            {
//                printf("wait failed\n");
//                break;
//            }
//            else
//            {
//                printf("子函数还没有退出,继续等待\n");
//                sleep(1);
//            }
//        }
//        sleep(5);
//    }
//    return 0;
//}


#define MAX_NUMBER 5
typedef void (*task) ();
task Task[MAX_NUMBER];
void task1()
{
    printf("I am executing task1\n");
}

void task2()
{
    printf("I am executing task2\n");
}

void task3()
{
    printf("I am executing task3\n");
}

void InitTask()
{
    task Task[MAX_NUMBER];
    for(int i = 0; i<MAX_NUMBER; i++)
    {
        Task[i] = NULL;
    }
}

int AddTask(task t)
{
    int pos = 0;
    for(pos = 0; pos < MAX_NUMBER; pos++)
    {
        if(!Task[pos])
        {
            break;
        }
    }
    if(pos == MAX_NUMBER)
    {
        return -1;
    }
    Task[pos] = t;
    return 0;
}

void ExauteTask()
{
    for(int i = 0; i < MAX_NUMBER; i++)
    {
        if(Task[i])
        {
            Task[i]();
        }
    }
}

int main()
{
    pid_t id = fork();
    
    if(id < 0)
    {
        perror("fork fail\n");
        return 1;
    }
    else if(id == 0)
    {
        //child
        int cnt = 5;
        while(cnt)
        { 
            printf("I am a child, pid:%d, ppid:%d, cnt:%d\n", getpid(), getppid(), cnt);
            cnt--;
            sleep(1);
        }
        exit(1);
    }
    else
    {
        //parent
        InitTask();
        AddTask(task1);
        AddTask(task2);
        AddTask(task3);
        int status = 0;
        while(1)
        {
            //提供非阻塞轮询
            pid_t ret = waitpid(id, &status, WNOHANG);
            if(ret > 0)
            {
                if(WIFEXITED(status))
                {
                    printf("进程正常跑完，退出码为%d\n", WEXITSTATUS(status));
                }
                else
                {
                    printf("程序异常\n");
                }

                break;
            }
            else if(ret < 0)
            {
                printf("wait failed\n");
                break;
            }
            else
            {
                //printf("子函数还没有退出,继续等待\n");
                ExauteTask();
                sleep(2);
            }
        }
        sleep(5);
    }
    return 0;
}
